// 性能监控工具
export class PerformanceMonitor {
    private static instance: PerformanceMonitor
    private metrics: Map<string, number[]> = new Map()
    private observers: PerformanceObserver[] = []

    private constructor() {
        this.initializeObservers()
    }

    public static getInstance(): PerformanceMonitor {
        if (!PerformanceMonitor.instance) {
            PerformanceMonitor.instance = new PerformanceMonitor()
        }
        return PerformanceMonitor.instance
    }

    private initializeObservers() {
        if (typeof window === 'undefined') return

        // 监控 LCP (Largest Contentful Paint)
        if ('PerformanceObserver' in window) {
            try {
                const lcpObserver = new PerformanceObserver((list) => {
                    const entries = list.getEntries()
                    const lastEntry = entries[entries.length - 1] as any
                    if (lastEntry) {
                        this.recordMetric('LCP', lastEntry.startTime)
                    }
                })
                lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] })
                this.observers.push(lcpObserver)
            } catch (e) {
                console.warn('LCP observer not supported')
            }

            // 监控 FID (First Input Delay)
            try {
                const fidObserver = new PerformanceObserver((list) => {
                    const entries = list.getEntries()
                    entries.forEach((entry: any) => {
                        this.recordMetric('FID', entry.processingStart - entry.startTime)
                    })
                })
                fidObserver.observe({ entryTypes: ['first-input'] })
                this.observers.push(fidObserver)
            } catch (e) {
                console.warn('FID observer not supported')
            }

            // 监控 CLS (Cumulative Layout Shift)
            try {
                const clsObserver = new PerformanceObserver((list) => {
                    let clsValue = 0
                    const entries = list.getEntries()
                    entries.forEach((entry: any) => {
                        if (!entry.hadRecentInput) {
                            clsValue += entry.value
                        }
                    })
                    this.recordMetric('CLS', clsValue)
                })
                clsObserver.observe({ entryTypes: ['layout-shift'] })
                this.observers.push(clsObserver)
            } catch (e) {
                console.warn('CLS observer not supported')
            }
        }
    }

    // 记录自定义性能指标
    public recordMetric(name: string, value: number) {
        if (!this.metrics.has(name)) {
            this.metrics.set(name, [])
        }
        this.metrics.get(name)!.push(value)
    }

    // 开始计时
    public startTiming(name: string): () => void {
        const startTime = performance.now()
        return () => {
            const endTime = performance.now()
            this.recordMetric(name, endTime - startTime)
        }
    }

    // 获取指标统计
    public getMetricStats(name: string) {
        const values = this.metrics.get(name) || []
        if (values.length === 0) return null

        const sorted = [...values].sort((a, b) => a - b)
        return {
            count: values.length,
            min: sorted[0],
            max: sorted[sorted.length - 1],
            avg: values.reduce((sum, val) => sum + val, 0) / values.length,
            p50: sorted[Math.floor(sorted.length * 0.5)],
            p90: sorted[Math.floor(sorted.length * 0.9)],
            p95: sorted[Math.floor(sorted.length * 0.95)]
        }
    }

    // 获取所有指标
    public getAllMetrics() {
        const result: Record<string, any> = {}
        for (const [name] of this.metrics) {
            result[name] = this.getMetricStats(name)
        }
        return result
    }

    // 清理观察者
    public cleanup() {
        this.observers.forEach(observer => observer.disconnect())
        this.observers = []
    }
}

// 性能装饰器
export function measurePerformance(metricName: string) {
    return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
        const method = descriptor.value
        descriptor.value = async function (...args: any[]) {
            const monitor = PerformanceMonitor.getInstance()
            const endTiming = monitor.startTiming(metricName)
            try {
                const result = await method.apply(this, args)
                return result
            } finally {
                endTiming()
            }
        }
    }
}

// React Hook for performance monitoring
export function usePerformanceMonitor() {
    const monitor = PerformanceMonitor.getInstance()

    const recordMetric = (name: string, value: number) => {
        monitor.recordMetric(name, value)
    }

    const startTiming = (name: string) => {
        return monitor.startTiming(name)
    }

    const getMetrics = () => {
        return monitor.getAllMetrics()
    }

    return {
        recordMetric,
        startTiming,
        getMetrics
    }
}

// 内存使用监控
export function getMemoryUsage() {
    if (typeof window === 'undefined' || !('memory' in performance)) {
        return null
    }

    const memory = (performance as any).memory
    return {
        usedJSHeapSize: memory.usedJSHeapSize,
        totalJSHeapSize: memory.totalJSHeapSize,
        jsHeapSizeLimit: memory.jsHeapSizeLimit,
        usedPercent: (memory.usedJSHeapSize / memory.jsHeapSizeLimit) * 100
    }
}

// 网络性能监控
export function getNetworkTiming(url: string) {
    if (typeof window === 'undefined') return null

    const entries = performance.getEntriesByName(url, 'navigation') as PerformanceNavigationTiming[]
    if (entries.length === 0) return null

    const entry = entries[0]
    return {
        dns: entry.domainLookupEnd - entry.domainLookupStart,
        tcp: entry.connectEnd - entry.connectStart,
        request: entry.responseStart - entry.requestStart,
        response: entry.responseEnd - entry.responseStart,
        total: entry.responseEnd - entry.requestStart
    }
}